home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / UTIL / DJGPP2 / CONTRIB / MAN_PC.ZIP / man_pc / whatis / whatis.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-20  |  6.3 KB  |  365 lines

  1. #undef DEBUG
  2. #undef CHECK_MAGIC
  3.  
  4. /*
  5.  *    whatis - show description of word from man database
  6.  * 
  7.  *     whatis [-l] [-P path] [-s sect] name ...
  8.  *
  9.  *    bugs:
  10.  *        - need more error checking (of data in database)
  11.  *        - perhaps a "magic number" for the database? it is
  12.  *          written, but #ifdef CHECK_MAGIC.
  13.  *
  14.  *    todo:
  15.  *        - allow "-s n name name -s m name ..."
  16.  *        - allow continuation lines in database:
  17.  *
  18.  *            name\
  19.  *            %1\
  20.  *            %...
  21.  */
  22.  
  23. static char *rcsid_whatis_c = "$Id: whatis.c,v 2.0 1992/09/13 05:02:44 rosenkra Exp $";
  24. static char *version = "whatis 2.0 92/09/13 rosenkra@convex.com";
  25. static char *myname  = "whatis";
  26.  
  27. /*
  28.  * $Log: whatis.c,v $
  29.  * Revision 2.0  1992/09/13  05:02:44  rosenkra
  30.  * total rewrite. this if first rev of this file.
  31.  *
  32.  *
  33.  */
  34.  
  35. #include <stdio.h>
  36. #include <string.h>
  37. #include <stdlib.h>
  38. #include <ctype.h>
  39.  
  40.  
  41. #include "whatis.h"
  42.  
  43.  
  44. /*
  45.  *    we only need one record here. we read a record and check all the
  46.  *    command line args against it for a match
  47.  */
  48. struct rec    r;
  49.  
  50. char           *libpath = MANPATH;    /* path to database files (-P) */
  51. int        debugging = 0;        /* for -d */
  52.  
  53.  
  54. /*
  55.  *    fcn prototypes
  56.  */
  57. void        whatis (int, int, int, char **);
  58. void        usage (int);
  59. int        parse_record (char *, struct rec *);
  60. void        print_record (int, struct rec *);
  61. #ifdef CHECK_MAGIC
  62. int        check_magic (void);
  63. #endif
  64.  
  65.  
  66.  
  67.  
  68. /*------------------------------*/
  69. /*    main            */
  70. /*------------------------------*/
  71. void main (int argc, char *argv[])
  72. {
  73.     int    sect = -1;
  74.     int    verbose = 0;
  75.     char   *lpath;
  76.     char   *ps;
  77.  
  78.  
  79.  
  80.     /*
  81.      *   see if there is MANPATH in env. use it over default...
  82.      */
  83.     if ((lpath = getenv ("MANPATH")) != (char *) NULL)
  84.         libpath = lpath;
  85.     else if ((lpath = getenv ("MANDIR")) != (char *) NULL)
  86.         libpath = lpath;
  87. #ifdef DEBUG
  88.     else
  89.         fprintf (stderr, "whatis: environment variable MANPATH not set, using default\n");
  90. #endif
  91.  
  92.  
  93.     /*
  94.      *   parse args
  95.      */
  96.     for (argc--, argv++; argc && **argv == '-'; argc--, argv++)
  97.     {
  98.         switch (*(*argv+1))
  99.         {
  100.         case 'P':            /* path for db */
  101.         case 'M':
  102.             argc--, argv++;
  103.             if (argc < 1)
  104.                 usage (1);
  105.             libpath = *argv;
  106.             break;
  107.  
  108.         case 's':            /* specific section */
  109.             argc--, argv++;
  110.             if (argc < 1)
  111.                 usage (1);
  112.             sect = **argv;
  113.             break;
  114.  
  115.         case 'l':            /* long (verbose) */
  116.             verbose = 1;
  117.             break;
  118.  
  119.         case 'd':            /* debug mode */
  120.             debugging = 1;
  121.             break;
  122.  
  123.         case 'v':            /* version */
  124.             printf ("%s\n", version);
  125.             exit (0);
  126.             break;
  127.  
  128.         case 'h':            /* help */
  129.             usage (0);
  130.             break;
  131.             
  132.         case '-':
  133.             switch (*(*argv+2))
  134.             {
  135.             case 'v':        /* --version */
  136.                 printf ("%s\n", version);
  137.                 exit (0);
  138.                 break;
  139.  
  140.             case 'h':        /* --help */
  141.                 usage (0);
  142.                 break;
  143.             }
  144.             break;
  145.         }
  146.     }
  147.  
  148.  
  149.  
  150.     /*
  151.      *   whatis what?
  152.      */
  153.     if (argc == 0)
  154.     {
  155.         fprintf (stderr,
  156.         "%s: you must specify an argument. consider using whatisin.\n",
  157.         myname);
  158.         usage (1);
  159.     }
  160.  
  161.  
  162.  
  163.     /*
  164.      *   not documented: if first arg is a number, use it for section...
  165.      */
  166.     if (isdigit(**argv))
  167.     {
  168.         sect = **argv;
  169.         argc--, argv++;
  170.     }
  171.  
  172.  
  173.  
  174.     /*
  175.      *   do it. if specific section, search it only. else search all
  176.      *   sections
  177.      */
  178.     if (sect != -1)
  179.     {
  180.         whatis (verbose, sect, argc, argv);
  181.     }
  182.     else
  183.     {
  184.         for (ps = SECTIONS; *ps; ps++)
  185.         {
  186.             sect = *ps;
  187.             whatis (verbose, sect, argc, argv);
  188.         }
  189.     }
  190.  
  191.  
  192.     exit (0);
  193. }
  194.  
  195.  
  196.  
  197.  
  198. /*------------------------------*/
  199. /*    whatis            */
  200. /*------------------------------*/
  201. void whatis (int verbose, int sect, int argc, char **argv)
  202. {
  203.  
  204. #define MAX_ARGS    100
  205.  
  206.     char        dbname[256];
  207.     char        buf[REC_SIZE];
  208.     register char **vp;
  209.     int        notfound[MAX_ARGS];
  210.     int        i;
  211.  
  212.  
  213.  
  214.     /*
  215.      *   FIXME: we should allocate space for the notfound list.
  216.      */
  217.     if (argc > MAX_ARGS)
  218.         argc = MAX_ARGS;
  219.  
  220.  
  221.  
  222.     /*
  223.      *   set up db name. section is really a single ascii char, not an
  224.      *   int. this is so we can have whatis for local, new, etc.
  225.      */
  226.     if (sect == -1)
  227.         /* orig behavior (just single "whatis" file, never used here) */
  228.         sprintf (dbname, "%s%s%s", libpath, SLASH, WHATIS);
  229.     else
  230.         /* new: whatis._[0-9lno]_ */
  231.         sprintf (dbname, "%s%s%s._%c_", libpath, SLASH, WHATIS, sect);
  232.  
  233.  
  234.  
  235.     /*
  236.      *   reopen stdin as this file...
  237.      */
  238.     if (debugging)
  239.         fprintf (stderr, "checking database file %s...\n", dbname);
  240.     if (freopen (dbname, "r", stdin) == (FILE *) NULL)
  241.     {
  242. /*        if (verbose || debugging)*/
  243.         if (debugging)
  244.             fprintf (stderr,
  245.                 "%s: could not access file %s\n",
  246.                  myname, dbname);
  247.  
  248.         return;
  249.     }
  250.  
  251.  
  252.  
  253. #ifdef CHECK_MAGIC
  254.     /*
  255.      *   check file's magic
  256.      */
  257.     if (check_magic ())
  258.     {
  259.         fprintf (stderr,
  260.             "%s: magic number is wrong for file %s\n",
  261.             myname, dbname);
  262.  
  263.         return;
  264.     }
  265. #endif
  266.  
  267.  
  268.  
  269.     /*
  270.      *   read file and compare. first assume we will not find anything
  271.      *   and flag list...
  272.      */
  273.     for (i = 0; i < MAX_ARGS; i++)
  274.         notfound[i] = 1;
  275.     while (1)
  276.     {
  277.         /*
  278.          *   get raw record from file
  279.          */
  280.         fgets (buf, REC_SIZE-1, stdin);
  281.         if (feof (stdin))
  282.             break;
  283.         if (debugging)
  284.             fprintf (stderr, "%s", buf);
  285.  
  286.  
  287.  
  288.         /*
  289.          *   skip comment or blank lines
  290.          */
  291.         if (buf[0] == '#' || buf[0] == '\0' || buf[0] == '\n')
  292.             continue;
  293.  
  294.  
  295.  
  296.         /*
  297.          *   parse the record and store in r
  298.          */
  299.         parse_record (buf, &r);
  300.  
  301.         if (debugging)
  302.         {
  303.         fprintf (stderr, "name:    %s\n", r.name ? r.name : "(NULL)");
  304.         fprintf (stderr, "section: %s\n", r.section ? r.section : "(NULL)");
  305.         fprintf (stderr, "subsect: %s\n", r.subsect ? r.subsect : "(NULL)");
  306.         fprintf (stderr, "desc:    %s\n", r.desc ? r.desc : "(NULL)");
  307.         }
  308.  
  309.  
  310.  
  311.         /*
  312.          *   compare record's name field to all args from orig
  313.          *   command line. if we find one, flag notfound list
  314.          */
  315.         for (i = 0, vp = argv; i < argc && *vp; vp++, i++)
  316.         {
  317.             if (!strncmp (r.name, *vp, strlen (*vp)))
  318.             {
  319.                 print_record (verbose, &r);
  320.                 notfound[i] = 0;
  321.             }
  322.         }
  323.     }
  324.  
  325.  
  326.  
  327.     /*
  328.      *   print a message if we didn't find anything for the cmdline arg
  329.      */
  330.     if (verbose)
  331.     {
  332.         for (i = 0; i < argc; i++)
  333.         {
  334.             if (notfound[i])
  335.             {
  336.                 printf ("nothing found in section %c for %s\n",
  337.                     sect, argv[i]);
  338.             }
  339.         }
  340.     }
  341.  
  342.     return;
  343. }
  344.  
  345.  
  346.  
  347.  
  348. /*------------------------------*/
  349. /*    usage            */
  350. /*------------------------------*/
  351. void usage (int excode)
  352. {
  353. #define U    fprintf
  354.  
  355. U(stderr,"usage: %s [-l] [-P path] [-s section] name ...\n", myname);
  356. U(stderr,"       -l          long list\n");
  357. U(stderr,"       -P path     alternative path to databases (MANPATH)\n");
  358. U(stderr,"       -s section  search single section, not all\n");
  359. U(stderr,"       name        valid name of a command, etc. if name is unknown,\n");
  360. U(stderr,"                   consider using whatisin(1) or apropos(1).\n");
  361.  
  362. exit (excode);
  363. }
  364.  
  365.